# GPU Usage Guide
The **GPU (Graphics Processing Unit)** is a dedicated processor in a device that is primarily responsible for graphics rendering and image processing. If a device is compared to a computer:
- The **CPU** is responsible for “thinking” — processing logic and running programs.
- The **GPU** is responsible for “drawing” — rendering content into images displayed on the screen.
Without a GPU, graphical interfaces, games, videos, and animations cannot be rendered efficiently. GPU performance directly affects the smoothness of graphics processing and the power consumption of the device.
| **Use Case** | **Description** |
| --- | --- |
| **System UI** | **Boot animations, desktop rendering, application switching, drop-down menus, and other UI rendering** |
| **Gaming & Entertainment** | **3D games, animation effects, AR applications, and other graphics rendering** |
| **Video Playback** | **Video color processing, image enhancement, and HDR effects** |
| **Camera & Photography** | **Viewfinder rendering, filter effects, and image enhancement** |
| **General Computing** | **Assists the CPU with parallel computing, such as face recognition and AI application acceleration** |
# GPU Configuration
|
Category
|
M1 Description
|
L1 Description
|
| --- | --- | --- |
| **Application Processor** | **Octa-core 64-bit ARM Kryo™ 260 processor:**
**4 × A73 @ 2.0 GHz, 1 MB L2 cache**
**4 × A53 @ 1.8 GHz, 512 KB L2 cache** | **Quad-core 64-bit ARM processor:**
**4 × A53 @ 2.0 GHz, 512 KB L2 cache** |
| **GPU** | **64-bit Adreno™ 610 @ 1050 MHz** | **64-bit Adreno™ 702 @ 845 MHz** |
| **Display Interface** | **1 × Micro HDMI interface, Micro HDMI 2.0 (frame rate\*); Encoding: 1080p (H.264/H.265) @ 60 fps\*; Decoding: 1080p (H.264/H.265/VP9) @ 60 fps\***
**1 × FPC connector, MIPI-compliant FHD+ (1080 × 2520) @ 60 fps\*** | **1 × Micro HDMI interface①, HDMI 2.0 (frame rate TBD\*); Encoding: 1080p (H.264/H.265) @ 60 fps\*; Decoding: 1080p (H.264/H.265/VP9) @ 60 fps\***
**1 × FPC connector①, MIPI-compliant FHD+ (1080 × 2520) @ 60 fps\*** |
# GPU Usage
## **Android** 4K High-Definition Video Playback
```{image} images/image_F2GRbtmaWoXZiuxS5qccFZM5n3t.webp
:width: 1920px
:height: 1080px
:align: center
```
## Debian OpenCV GPU Acceleration Development and Verification
### Preparation
#### Development Environment
- **PC:** Windows
- **Development Board:** Quectel Pi M1
- **Operating System:** Debian GNU/Linux 13
#### Development Tools
- **VS Code:** Used to write and modify the Benchmark source code.
- **ADB (Android Debug Bridge):** Used to connect to the development board, execute Linux commands, compile programs, and run applications.
**Note:** Except for source code editing, all Linux commands described in this document, including software installation, environment verification, program compilation, and program execution, are executed in the ADB Shell.
#### Connect to the Development Board
On the PC, open the ADB folder, enter CMD in the address bar to open a command prompt, and run:
```plaintext
adb devices
```
Confirm that the development board is connected. For example:
```plaintext
List of devices attached
xxxxxxxx device
```
Enter the development board:
```plaintext
adb shell
```
### Test Purpose
Install the official Debian OpenCV 4.10.0 package and verify whether Debian can use the Qualcomm OpenCL Runtime included in the system image to access the Adreno GPU and enable OpenCL GPU acceleration.
### Test Environment
| **Item** |
Details
|
| --- | --- |
| Development Board | Quectel Pi M1(QSM200U) |
| Operating System | Debian GNU/Linux 13 |
| Debian OpenCV | 4.10.0 |
| GPU | Qualcomm Adreno 610 |
| OpenCL Runtime | Qualcomm OpenCL Runtime |
### Install OpenCV from the Official Debian Repository
```plaintext
apt update
apt install g++ pkg-config libopencv-dev python3-opencv
```
Verify the installation after it is complete:
```plaintext
opencv_version
pkg-config --modversion opencv4
dpkg -l | grep opencv
```
Verification results:
- opencv_version: 4.10.0
- pkg-config: 4.10.0
- dpkg: Debian OpenCV 4.10.0
### Verify the OpenCL Runtime
Check the OpenCL libraries available in the system:
```plaintext
find /usr/lib -name "libOpenCL*"
```
Confirm that the following libraries are present:
```plaintext
libOpenCL.so
libOpenCL.so.1
libOpenCL.so.1.2
libOpenCL_adreno.so
```
### Write the Benchmark Program
Create the opencv_gpu_benchmark.cpp file in VS Code.
```plaintext
#include
#include
#include
#include
static double run_cpu(const cv::Mat &src, int loops, cv::Mat &result)
{
cv::ocl::setUseOpenCL(false);
cv::Mat current = src.clone();
cv::Mat next;
for (int i = 0; i < 5; ++i) {
cv::multiply(current, 1.000001, next);
current = next;
}
current = src.clone();
const int64 start = cv::getTickCount();
for (int i = 0; i < loops; ++i) {
cv::multiply(current, 1.000001, next);
current = next;
}
const int64 end = cv::getTickCount();
result = current.clone();
return (end - start) * 1000.0 / cv::getTickFrequency();
}
static double run_gpu(const cv::Mat &src, int loops, cv::Mat &result)
{
cv::ocl::setUseOpenCL(true);
if (!cv::ocl::useOpenCL()) {
std::cerr << "OpenCL could not be enabled." << std::endl;
return -1.0;
}
cv::UMat current;
cv::UMat next;
src.copyTo(current);
for (int i = 0; i < 5; ++i) {
cv::multiply(current, 1.000001, next);
current = next;
}
src.copyTo(current);
cv::ocl::finish();
const int64 start = cv::getTickCount();
for (int i = 0; i < loops; ++i) {
cv::multiply(current, 1.000001, next);
current = next;
}
cv::ocl::finish();
const int64 end = cv::getTickCount();
current.copyTo(result);
return (end - start) * 1000.0 / cv::getTickFrequency();
}
int main(int argc, char **argv)
{
if (argc != 2) {
std::cout << "Usage: " << argv[0] << " cpu|gpu|both" << std::endl;
return 1;
}
const std::string mode = argv[1];
const int loops = 500;
cv::Mat src(2160, 3840, CV_32FC1);
cv::randu(src, 0.0f, 1.0f);
std::cout << "OpenCV version: " << CV_VERSION << std::endl;
std::cout << "haveOpenCL: " << cv::ocl::haveOpenCL() << std::endl;
std::cout << "Image size: 3840x2160, CV_32FC1" << std::endl;
std::cout << "Loops: " << loops << std::endl;
if (mode == "cpu") {
cv::Mat cpu_result;
const double cpu_ms = run_cpu(src, loops, cpu_result);
std::cout << "Mode: CPU" << std::endl;
std::cout << "CPU total time: " << cpu_ms << " ms" << std::endl;
std::cout << "CPU average time: "
<< cpu_ms / loops << " ms" << std::endl;
}
else if (mode == "gpu") {
cv::ocl::Context context;
if (!context.create(cv::ocl::Device::TYPE_GPU)) {
std::cerr << "Failed to create GPU context." << std::endl;
return 1;
}
cv::ocl::Device device = context.device(0);
std::cout << "Mode: GPU" << std::endl;
std::cout << "Device name: " << device.name() << std::endl;
std::cout << "Vendor: " << device.vendorName() << std::endl;
std::cout << "OpenCL version: " << device.version() << std::endl;
cv::Mat gpu_result;
const double gpu_ms = run_gpu(src, loops, gpu_result);
if (gpu_ms < 0.0) {
return 1;
}
std::cout << "GPU total time: " << gpu_ms << " ms" << std::endl;
std::cout << "GPU average time: "
<< gpu_ms / loops << " ms" << std::endl;
}
else if (mode == "both") {
cv::Mat cpu_result;
cv::Mat gpu_result;
const double cpu_ms = run_cpu(src, loops, cpu_result);
const double gpu_ms = run_gpu(src, loops, gpu_result);
if (gpu_ms < 0.0) {
return 1;
}
const double max_difference =
cv::norm(cpu_result, gpu_result, cv::NORM_INF);
std::cout << "Mode: BOTH" << std::endl;
std::cout << "CPU average time: "
<< cpu_ms / loops << " ms" << std::endl;
std::cout << "GPU average time: "
<< gpu_ms / loops << " ms" << std::endl;
std::cout << "Speedup: "
<< cpu_ms / gpu_ms << "x" << std::endl;
std::cout << "Maximum result difference: "
<< max_difference << std::endl;
if (max_difference < 0.01) {
std::cout << "Result check: PASS" << std::endl;
} else {
std::cout << "Result check: FAIL" << std::endl;
return 1;
}
}
else {
std::cerr << "Invalid mode. Use cpu, gpu or both." << std::endl;
return 1;
}
return 0;
}
```
The program mainly performs the following functions:
- Creates a test image
- Executes cv::multiply() on the CPU
- Executes cv::multiply() on the GPU using UMat
- Measures the average execution time of the CPU and GPU separately
- Verifies that the CPU and GPU calculation results are consistent
- Outputs the GPU acceleration ratio (Speedup)
### Compile the Benchmark
Save the opencv_gpu_benchmark.cpp file created in VS Code to the ADB folder on the PC, and then push it to the development board:
```bash
adb push opencv_gpu_benchmark.cpp /data/local/tmp/
```
Enter the source directory:
```plaintext
cd /data/local/tmp
```
Compile:
```bash
g++ -O2 opencv_gpu_benchmark.cpp -o opencv_gpu_benchmark $(pkg-config --cflags --libs opencv4)
```
The executable file is generated:
```plaintext
opencv_gpu_benchmark
```
### Run the Benchmark
```plaintext
export LD_LIBRARY_PATH=/opt/qcom/lib:$LD_LIBRARY_PATH
```
```plaintext
./opencv_gpu_benchmark both
```
Running result:
```plaintext
OpenCV version: 4.10.0
haveOpenCL: 1
CPU average time: 28.9083 ms
GPU average time: 0.0474746 ms
Speedup: 608.92x
Maximum result difference: 0.000506639
Result check: PASS
```
### Test Notes
In this test, the official Debian OpenCV GPU Benchmark achieved a GPU speedup of approximately 608.92×.
It should be noted that the test program uses only the OpenCV cv::multiply() operator for performance verification. This is a basic OpenCL functionality test with a relatively small computational workload. As a result, the GPU execution time is close to the timing precision of the benchmark, which causes the calculated speedup ratio to be significantly higher than expected.
Therefore, the Benchmark result is mainly used to verify that OpenCV can successfully invoke the GPU for OpenCL computation. The 608.92× result should not be regarded as an overall GPU performance metric.
## Frequently Asked Questions
### Device UI Lag or Frame Drops?
- Check whether too many applications are running in the background and close unnecessary programs.
- If the device is overheating, allow it to cool down. The operating frequency will automatically recover after the temperature decreases.
### Screen Artifacts or Display Abnormalities?
- Check whether the HDMI cable and display connections are secure.
- Confirm that the screen or monitor resolution and refresh rate are configured correctly.
- Try another cable or display to rule out hardware issues.
- If a new LCD screen is being used, make sure its specifications and resolution are compatible with the device.
### Large Games or 3D Applications Crash?
- The device GPU is entry-level, and extremely demanding applications may exceed its performance capabilities.
- Try lowering the graphics quality or resolution settings.
- Ensure proper heat dissipation and avoid covering or blocking the device.
### GPU Overheating or High Power Consumption?
- Heat generation under high GPU load is normal. The system automatically reduces the operating frequency when necessary to provide thermal protection.
- Check whether any applications are continuously using the GPU, such as background video playback or animations.